package sunyu.service.shiro.impl;

import com.github.pagehelper.ISelect;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sunyu.kit.common.StringKit;
import sunyu.mapper.shiro.RoleMapper;
import sunyu.mapper.shiro.UserMapper;
import sunyu.mapper.shiro.UserRoleMapper;
import sunyu.mapper.shiro.pojo.Role;
import sunyu.mapper.shiro.pojo.User;
import sunyu.mapper.shiro.pojo.UserRoleKey;
import sunyu.service.shiro.UserService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户管理服务
 *
 * @author 孙宇
 */
@Service("userService")
public class UserServiceImpl implements UserService {

    @Resource(name = "userMapper")
    private UserMapper userMapper;

    @Resource(name = "userRoleMapper")
    private UserRoleMapper userRoleMapper;

    @Resource(name = "roleMapper")
    private RoleMapper roleMapper;

    @Override
    @Transactional
    public Boolean insert(User user,
                          String roleIds) {
        if (userMapper.insert(user) > 0) {
            updateUserRole(user, roleIds);

            return true;
        }
        return false;
    }

    /**
     * 更新用户与角色的关系
     *
     * @param user
     * @param roleIds
     */
    private void updateUserRole(final User user,
                                String roleIds) {
        deleteUserRole(user.getId());

        if (StringKit.isNotBlank(roleIds)) {
            for (String roleId : roleIds.split(",")) {
                UserRoleKey ur = new UserRoleKey();
                ur.setUserId(user.getId());
                ur.setRoleId(roleId);
                userRoleMapper.insert(ur);
            }
        }
    }

    private void deleteUserRole(final String userId) {
        Map<String, Object> params = new HashMap<String, Object>() {{
            put("userId", userId);
        }};
        userRoleMapper.delete(params);
    }


    @Override
    public List<User> select(Page page,
                             Map<String, Object> params) {
        if (page != null) {
            PageHelper.startPage(page.getPageNum(), page.getPageSize(), page.isCount());
        }
        return userMapper.select(params);
    }

    @Override
    public Long count(Map<String, Object> params) {
        return PageHelper.count(new ISelect() {
            @Override
            public void doSelect() {
                userMapper.select(params);
            }
        });
    }

    @Override
    public Boolean delete(String id) {
        deleteUserRole(id);

        if (userMapper.deleteByPrimaryKey(id) > 0) {
            return true;
        }
        return false;
    }

    @Override
    public User selectById(String id) {
        return userMapper.selectByPrimaryKey(id);
    }

    @Override
    public Boolean update(User user,
                          String roleIds) {
        updateUserRole(user, roleIds);

        if (userMapper.updateByPrimaryKeySelective(user) > 0) {
            return true;
        }
        return false;
    }

    @Override
    public String getRoleIds(String userId) {
        String roleIds = "[";
        Map<String, Object> params = new HashMap<String, Object>() {{
            put("userId", userId);
        }};
        List<UserRoleKey> urs = userRoleMapper.select(params);
        if (urs != null && urs.size() > 0) {
            for (int i = 0; i < urs.size(); i++) {
                if (i > 0) {
                    roleIds += ",";
                }
                roleIds += "'" + urs.get(i).getRoleId() + "'";
            }
        }
        return roleIds + "]";
    }

    @Override
    public List<Role> getRoles(String userId) {
        User user = userMapper.selectByPrimaryKey(userId);
        Map<String, Object> params = new HashMap<String, Object>() {{
            put("userId", user.getId());
        }};
        List<UserRoleKey> urs = userRoleMapper.select(params);
        if (urs != null && urs.size() > 0) {
            List<Role> roles = new ArrayList<>();
            for (UserRoleKey ur : urs) {
                roles.add(roleMapper.selectByPrimaryKey(ur.getRoleId()));
            }
            return roles;
        }
        return null;
    }
}
